home *** CD-ROM | disk | FTP | other *** search
/ Mac Easy 2010 May / Mac Life Ubuntu.iso / casper / filesystem.squashfs / usr / share / python-support / python-gdata / atom / http_interface.py < prev    next >
Encoding:
Python Source  |  2008-10-15  |  5.1 KB  |  159 lines

  1. #!/usr/bin/python
  2. #
  3. # Copyright (C) 2008 Google Inc.
  4. #
  5. # Licensed under the Apache License, Version 2.0 (the "License");
  6. # you may not use this file except in compliance with the License.
  7. # You may obtain a copy of the License at
  8. #
  9. #      http://www.apache.org/licenses/LICENSE-2.0
  10. #
  11. # Unless required by applicable law or agreed to in writing, software
  12. # distributed under the License is distributed on an "AS IS" BASIS,
  13. # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
  14. # See the License for the specific language governing permissions and
  15. # limitations under the License.
  16.  
  17. """This module provides a common interface for all HTTP requests.
  18.  
  19.   HttpResponse: Represents the server's response to an HTTP request. Provides
  20.       an interface identical to httplib.HTTPResponse which is the response
  21.       expected from higher level classes which use HttpClient.request.
  22.  
  23.   GenericHttpClient: Provides an interface (superclass) for an object 
  24.       responsible for making HTTP requests. Subclasses of this object are
  25.       used in AtomService and GDataService to make requests to the server. By
  26.       changing the http_client member object, the AtomService is able to make
  27.       HTTP requests using different logic (for example, when running on 
  28.       Google App Engine, the http_client makes requests using the App Engine
  29.       urlfetch API). 
  30. """
  31.  
  32.  
  33. __author__ = 'api.jscudder (Jeff Scudder)'
  34.  
  35.  
  36. import StringIO
  37.  
  38.  
  39. USER_AGENT = '%s GData-Python/1.2.2'
  40.  
  41.  
  42. class Error(Exception):
  43.   pass
  44.  
  45.  
  46. class UnparsableUrlObject(Error):
  47.   pass
  48.  
  49.  
  50. class ContentLengthRequired(Error):
  51.   pass
  52.   
  53.  
  54. class HttpResponse(object):
  55.   def __init__(self, body=None, status=None, reason=None, headers=None):
  56.     """Constructor for an HttpResponse object. 
  57.  
  58.     HttpResponse represents the server's response to an HTTP request from
  59.     the client. The HttpClient.request method returns a httplib.HTTPResponse
  60.     object and this HttpResponse class is designed to mirror the interface
  61.     exposed by httplib.HTTPResponse.
  62.  
  63.     Args:
  64.       body: A file like object, with a read() method. The body could also
  65.           be a string, and the constructor will wrap it so that 
  66.           HttpResponse.read(self) will return the full string.
  67.       status: The HTTP status code as an int. Example: 200, 201, 404.
  68.       reason: The HTTP status message which follows the code. Example: 
  69.           OK, Created, Not Found
  70.       headers: A dictionary containing the HTTP headers in the server's 
  71.           response. A common header in the response is Content-Length.
  72.     """
  73.     if body:
  74.       if hasattr(body, 'read'):
  75.         self._body = body
  76.       else:
  77.         self._body = StringIO.StringIO(body)
  78.     else:
  79.       self._body = None
  80.     if status is not None:
  81.       self.status = int(status)
  82.     else:
  83.       self.status = None
  84.     self.reason = reason
  85.     self._headers = headers or {}
  86.  
  87.   def getheader(self, name, default=None):
  88.     if name in self._headers:
  89.       return self._headers[name]
  90.     else:
  91.       return default
  92.     
  93.   def read(self, amt=None):
  94.     if not amt:
  95.       return self._body.read()
  96.     else:
  97.       return self._body.read(amt)
  98.  
  99.  
  100. class GenericHttpClient(object):
  101.   debug = False
  102.  
  103.   def __init__(self, http_client, headers=None):
  104.     """
  105.     
  106.     Args:
  107.       http_client: An object which provides a request method to make an HTTP 
  108.           request. The request method in GenericHttpClient performs a 
  109.           call-through to the contained HTTP client object.
  110.       headers: A dictionary containing HTTP headers which should be included
  111.           in every HTTP request. Common persistent headers include 
  112.           'User-Agent'.
  113.     """
  114.     self.http_client = http_client
  115.     self.headers = headers or {}
  116.  
  117.   def request(self, operation, url, data=None, headers=None):
  118.     all_headers = self.headers.copy()
  119.     if headers:
  120.       all_headers.update(headers)
  121.     return self.http_client.request(operation, url, data=data, 
  122.         headers=all_headers)
  123.  
  124.   def get(self, url, headers=None):
  125.     return self.request('GET', url, headers=headers)
  126.  
  127.   def post(self, url, data, headers=None):
  128.     return self.request('POST', url, data=data, headers=headers)
  129.  
  130.   def put(self, url, data, headers=None):
  131.     return self.request('PUT', url, data=data, headers=headers)
  132.  
  133.   def delete(self, url, headers=None):
  134.     return self.request('DELETE', url, headers=headers)
  135.  
  136.  
  137. class GenericToken(object):
  138.   """Represents an Authorization token to be added to HTTP requests.
  139.   
  140.   Some Authorization headers included calculated fields (digital
  141.   signatures for example) which are based on the parameters of the HTTP
  142.   request. Therefore the token is responsible for signing the request
  143.   and adding the Authorization header. 
  144.   """
  145.   def perform_request(self, http_client, operation, url, data=None, 
  146.                       headers=None):
  147.     """For the GenericToken, no Authorization token is set."""
  148.     return http_client.request(operation, url, data=data, headers=headers)
  149.  
  150.   def valid_for_scope(self, url):
  151.     """Tells the caller if the token authorizes access to the desired URL.
  152.     
  153.     Since the generic token doesn't add an auth header, it is not valid for
  154.     any scope.
  155.     """
  156.     return False
  157.  
  158.  
  159.